/*
 * Copyright (C) 2007-2008  Hylke van der Schaaf
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, in version 3 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package hextd.network;

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Timer;
import java.util.ArrayList;

/**
 *
 * @author hylke
 */
public class NetworkClient implements Runnable, NetworkConnector, LineListener {

	private Thread threadConnectWaiter;
	private NetworkConnection connection;
	//
	private String server;
	private int port;
	private NetworkUser user;
	private ArrayList<LineListener> listeners;
	private Timer flushTimer = new Timer("NetworkClientFlushTimer", true);

	public NetworkClient(NetworkUser user) {
		this.user = user;
		this.listeners = new ArrayList<LineListener>();
	}

	public void addLineListener(LineListener l) {
		this.listeners.add(l);
	}

	public void removeLineListener(LineListener l) {
		this.listeners.remove(l);
	}

	public void setServer(String server) {
		this.server = server;
	}

	public void setPort(int port) {
		this.port = port;
	}

	public void connect() {
		threadConnectWaiter = new Thread(this, "ClientConnectionMaker");
		threadConnectWaiter.start();
	}

	private void doConnect(String server, int port) {
		try {
			Socket socketClient = new Socket(server, port);
			socketClient.setKeepAlive(true);
			socketClient.setSoTimeout(300000);
			//this.connection = new NetworkConnection(socketClient, flushTimer);
			this.connection = new NetworkConnection(socketClient);
			this.connection.addLineListener(this);

		} catch (UnknownHostException e) {
			this.user.connectionFailed(connection, "Don't know about host: " + server + ".");
			return;
		} catch (IOException e) {
			this.user.connectionFailed(connection, "Couldn't get I/O for the connection to: " + server + ".");
			return;
		}
		this.user.connectionEstablished(connection);
	}

	public void stopClient() {
		if (this.connection != null) {
			this.connection.removeLineListener(this);
			this.connection.close();
		}
	}

	@Override
	public void lineReceived(String line) {
		for (LineListener l : this.listeners) {
			l.lineReceived(line);
		}
	}

	@Override
	public void inputStopped() {
		this.user.connectionLost(connection);
		for (LineListener l : this.listeners) {
			l.inputStopped();
		}
		connection = null;
		if (flushTimer != null) {
			flushTimer.cancel();
			flushTimer = null;
		}
	}

	@Override
	public void sendLine(String line) {
		if (connection != null) {
			connection.sendLine(line);
		}
	}

	@Override
	public void run() {
		this.doConnect(this.server, this.port);
	}
}
